Метод 13: generate_cooking_payload()

Домен: SIMULATION | Контур: Списание продуктов на приготовление блюда

WarningОграничение публичной документации

В открытом доступе представлена демонстрационная версия метода. В настоящей публичной документации отображены не все шаги, технические сценарии и приватные эндпоинты для системы цифровых симуляторов бизнес-процессов.

  • Полная спецификация метода: Будет доступна только во внутреннем контуре разработки (Confluence / Swagger Enterprise).

1. Бизнес-спецификация метода

  • Идентификатор метода: BPDS-SIM-M013
  • Системное имя: generate_cooking_payload(context: TwinContext): CookRecipePayload
  • Микросервис: simulation-core-engine
  • Домен: SIMULATION
  • Класс / Компонент: simulation.engine.helpers.CookingPayloadGenerator

1.1. Описание логики работы

Этот метод отвечает за автоматический подбор конкретных упаковок и позиций продуктов в холодильнике бэкенда для приготовления выбранного блюда, когда на Шаге 9 выпал сценарий Готовки (SCENARIO_COOKING_MEAL).

Процесс устроен следующим образом: симулятор берет жестко заданный рецепт (например, «Банановый смузи») и проверяет, лежат ли прямо сейчас в холодильнике пользователя необходимые для него продукты — молоко и бананы. Метод находит уникальные идентификаторы (UUID) этих продуктов, проверяет, хватает ли их количества (веса или штук) для выполнения рецепта. Так как в системе нет параметров порчи, метод берет первые попавшиеся подходящие под рецепт UUID продуктов из массива, списывает нужную по рецепту дозу и упаковывает эти данные в команду кулинарного списания для отправки в приложение.

1.2. Пошаговое выполнение

  1. Проверка состава: Метод извлекает список продуктов пользователя, сохраненный в объекте TwinContext.
  2. Поиск по категориям: Программа сопоставляет требования рецепта с реальным содержимым холодильника. Она ищет продукт из категории фруктов (FRUITS — Банан) и продукт из категории молочной продукции (DAIRY — Молоко).
  3. Контроль объема: Симулятор сверяет имеющийся вес бананов и количество молока с нормативом рецепта. Если продуктов физически не хватает для приготовления минимальной порции, выполнение прерывается с ошибкой.
  4. Сборка команды: Найденные уникальные номера (fridge_item_id) продуктов и нужный объем их списания упаковываются в иммутабельный DTO-объект для передачи сетевому контуру отправки (Метод 15).

2. Диаграмма последовательности метода (Вход и Выход флоу)

Диаграмма наглядно показывает, как метод принимает контекст, проверяет наличие продуктов для рецепта в оперативной памяти и формирует команду кулинарного списания.

sequenceDiagram
    autonumber
    participant Core as Метод 3
    participant G as CookingPayloadGenerator
    participant RAM as Данные пользователя

    %% ВХОД МЕТОДА
    Core->>G: Вызов generateCookingPayload
    activate G
    Note over G: Вход метода: TwinContext со списком продуктов в холодильнике
    
    G->>RAM: Запрос списка продуктов rawFridgeSnapshot
    RAM-->>G: Возврат: Список продуктов Твина
    
    %% ВНУТРЕННИЙ ПОДБОР ИНГРЕДИЕНТОВ
    G->>G: Поиск продукта категории FRUITS
    G->>G: Поиск продукта категории DAIRY
    
    alt Ситуация: Продукты не найдены или их вес меньше рецептурного
        Note over G: Прерывание: Выброс ошибки IngredientDeficitException
    end
    
    G->>G: Формирование CookRecipePayload
    Note over G: Выход метода: Сформированный и готовый к отправке по сети DTO рецепта готовки
    
    G-->>Core: Возврат: Кулинарный пакет CookRecipePayload DTO
    deactivate G


3. Схемы данных и SQL-взаимодействие

Этот метод обрабатывает готовый массив продуктов внутри оперативной памяти симулятора и напрямую запросы к PostgreSQL симулятора на этом шаге не делает. Все UUID продуктов уже лежат в переданном объекте TwinContext.


4. Спецификация обмена данными (Вход / Выход)

Данные подготавливаются для отправки на прикладной эндпоинт готовки бэкенда приложения.

4.1. Входной состав холодильника пользователя в памяти (Входные параметры)

{
  "twin_id": "d3b07384-d113-4956-bf8a-e421cd7bf777",
  "current_tick": 105,
  "raw_fridge_snapshot": [
    {
      "fridge_item_id": "3cb294dd-e011-4f11-b552-111122223333",
      "sku": "BANANA_ECUADOR_KG",
      "category_id": "FRUITS",
      "quantity": 1.6950
    },
    {
      "fridge_item_id": "8fa1b432-8411-4c12-a111-9992345bcbc1",
      "sku": "MILK_AMAL_1L_3.2",
      "category_id": "DAIRY",
      "quantity": 2.0000
    }
  ]
}

4.2. Сформированная JSON-команда кулинарного списания (Выходные параметры для Метода 15)

Симулятор указывает бэкенду точные UUID продуктов, из которых нужно приготовить смузи:

{
  "recipe_id": "recipe_almaty_banana_smoothie_05",
  "target_dish_name": "Банановый Смузи на Молоке",
  "ingredients_to_spend": [
    {
      "fridge_item_id": "3cb294dd-e011-4f11-b552-111122223333",
      "sku": "BANANA_ECUADOR_KG",
      "spend_quantity": 0.5000
    },
    {
      "fridge_item_id": "8fa1b432-8411-4c12-a111-9992345bcbc1",
      "sku": "MILK_AMAL_1L_3.2",
      "spend_quantity": 1.0000
    }
  ]
}

5. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: BACKEND

Заголовок: Реализация хелпера кулинарного списания продуктов generate_cooking_payload

5.1. Что нужно сделать

  1. Создать Java-класс CookingPayloadGenerator в пакете simulation.engine.helpers и пометить его аннотацией @Component.
  2. Написать метод generateCookingPayload, принимающий TwinContext.
  3. С помощью Java Streams найти в списке context.rawFridgeSnapshot() первый попавшийся продукт с категорией FRUITS (содержащий в SKU слово BANANA) и первый продукт с категорией DAIRY (содержащий в SKU слово MILK).
  4. Добавить валидацию: если продукты не найдены или их текущее количество (quantity) меньше требуемого по рецепту (меньше 0.5000 для бананов и меньше 1.0000 для молока), выбрасывать контролируемое бизнес-исключение IngredientDeficitException.
  5. Сформировать результирующий DTO-объект CookRecipePayload, прописав туда ID рецепта recipe_almaty_banana_smoothie_05, и вернуть его оркестратору.

6. ЗАДАЧА ДЛЯ РАЗРАБОТЧИКА: МИГРАЦИЯ

Заголовок: Создание справочной таблицы рецептов recipe_ingredients_matrix в базе данных бэкенда для верификации списаний

6.1. Что нужно сделать

Чтобы прикладной эндпоинт готовки бэкенда приложения розничной сети мог успешно принимать команды от симулятора и проверять, что симулятор списывает ингредиенты строго по правильному стандарту, в СУБД бэкенда должна быть развернута справочная таблица рецептов.

-- Изменения для базы данных бэкенда розничной сети (схема public)
CREATE TABLE public.recipe_ingredients_matrix (
    recipe_id VARCHAR(64) NOT NULL,
    ingredient_sku VARCHAR(64) NOT NULL,
    standard_spend_quantity NUMERIC(10, 4) NOT NULL,
    CONSTRAINT pk_recipe_matrix PRIMARY KEY (recipe_id, ingredient_sku)
);

-- Засев нормативов Бананового Смузи для сверки транзакций симулятора
INSERT INTO public.recipe_ingredients_matrix (recipe_id, ingredient_sku, standard_spend_quantity) VALUES
('recipe_almaty_banana_smoothie_05', 'BANANA_ECUADOR_KG', 0.5000),
('recipe_almaty_banana_smoothie_05', 'MILK_AMAL_1L_3.2', 1.0000)
ON CONFLICT DO NOTHING;